package com.mavenq.fly.websocket.handler;


import com.mavenq.fly.utils.JsonUtils;
import com.mavenq.fly.websocket.service.WSConnectionService;
import com.mavenq.fly.websocket.entity.WSMessage;
import lombok.RequiredArgsConstructor;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

@RequiredArgsConstructor
public abstract class AbstractWSHandler extends TextWebSocketHandler {

    protected final WSConnectionService connectionService;
    protected final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(this.getClass());
    protected final org.springframework.web.socket.TextMessage PONG = new TextMessage("{\"type\":\"pong\"}");

    @Override
    public void afterConnectionEstablished(WebSocketSession session) {
        String token = (String) session.getAttributes().get("token");
        if (token == null || token.isEmpty()) {
            try {
                session.close(CloseStatus.POLICY_VIOLATION.withReason("缺少token"));
            } catch (Exception e) {
                log.error("关闭异常", e);
            }
            return;
        }
        connectionService.register(token, session);
        log.info("连接建立：sessionId={}, token={}", session.getId(), maskToken(token));
    }

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) {
        String token = (String) session.getAttributes().get("token");
        try {
            WSMessage msg = JsonUtils.fromJson(message.getPayload(), WSMessage.class);
            msg.setToken(token); // 补充token
            onMessage(session, msg);
        } catch (Exception e) {
            log.warn("消息解析失败：sessionId={}, 原文={}", session.getId(), message.getPayload());
            try {
                session.sendMessage(new TextMessage("{\"type\":\"error\",\"content\":\"消息格式错误\"}"));
            } catch (Exception ioEx) {
                log.error("回送错误失败", ioEx);
            }
        }
    }

    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) {
        log.error("传输错误：sessionId={}", session.getId(), exception);
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) {
        String token = (String) session.getAttributes().get("token");
        connectionService.unregister(token);
        log.info("连接关闭：sessionId={}, 状态={}, 原因={}", session.getId(), status.getCode(), status.getReason());
    }

    @Override
    public boolean supportsPartialMessages() {
        return false;
    }

    // 业务子类必须实现
    protected abstract void onMessage(WebSocketSession session, WSMessage msg);

    // 便捷方法
    protected void sendText(WebSocketSession session, String text) {
        try {
            if (session.isOpen()) session.sendMessage(new TextMessage(text));
        } catch (Exception e) {
            log.warn("发送文本失败：sessionId={}", session.getId(), e);
        }
    }

    protected void sendPong(WebSocketSession session) {
        try {
            if (session.isOpen()) session.sendMessage(PONG);
        } catch (Exception e) {
            log.warn("发送pong失败：sessionId={}", session.getId(), e);
        }
    }

    protected String maskToken(String token) {
        if (token == null || token.length() <= 6) return "****";
        return token.substring(0, 3) + "****" + token.substring(token.length() - 3);
    }
}